
#pragma once

#include "Common/Strings.h"
#include "Parameter.h"

using namespace System::Collections::Generic;

namespace ttg_internal
{
	namespace utils
	{
		///<summary>
		/// Wrapper for void parameter.
		///</summary>
		public ref class ParameterVoid :public Parameter
		{
			public:
				ParameterVoid(System::String ^name, ParameterInfo_Void ^info, ParameterSet ^owner)
					:Parameter(name, info, owner, nullptr)
				{ /*nothing*/ }
		};
		///<summary>
		/// Wrapper, that provides bool property for value.
		///</summary>
		public ref class ParameterBool :public Parameter
		{
			public:
				ParameterBool(System::String ^name, ParameterInfo_Bool ^info, ParameterSet ^owner)
					:Parameter(name, info, owner, "BoolValue")
				{ /*nothing*/ }
				///<summary>
				/// Bool version for Value property.
				///</summary>
				property bool BoolValue
				{
					bool get()
					{ return Value == "true"; }
					void set(bool value)
					{ Value = value ? "true" : "false"; }
				}
		};
		///<summary>
		/// Wrapper for string parameter.
		///</summary>
		public ref class ParameterString :public Parameter
		{
			public:
				ParameterString(System::String ^name, ParameterInfo_String ^info, ParameterSet ^owner)
					:Parameter(name, info, owner, nullptr)
				{ /*nothing*/ }
		};
		///<summary>
		/// Wrapper, that provides Index property for enum elements.
		///</summary>
		public ref class ParameterEnum :public Parameter
		{
			private:
				ParameterInfo_Enum ^_info;
			public:
				ParameterEnum(System::String ^name, ParameterInfo_Enum ^info, ParameterSet ^owner)
					:Parameter(name, info, owner, "Index")
				{ _info = info; }
				///<summary>
				/// Index of selected element.
				///</summary>
				property int Index
				{
					int get()
					{
						int res = 0;
						System::String ^cur = Value;
						for each (System::String ^e in _info->Elements)
						{
							if (e == cur)
								return res;
							else
								res++;
						}
						return -1;
					}
					void set(int value)
					{
						if (0 <= value && value < _info->Elements->Length)
							Value = _info->Elements[value];
					}
				}
		};
		///<summary>
		/// Wrapper, that provides int property for value.
		///</summary>
		public ref class ParameterInt64 :public Parameter
		{
			private:
				ParameterInfo_Int64 ^_info;
			public:
				ParameterInt64(System::String ^name, ParameterInfo_Int64 ^info, ParameterSet ^owner)
					:Parameter(name, info, owner, "Int64Value")
				{ _info = info; }
				///<summary>
				/// Int version for Value property.
				///</summary>
				property System::Int64 Int64Value
				{
					System::Int64 get()
					{ return System::Int64::Parse(Value); }
					void set(System::Int64 value)
					{ Value = value.ToString(); }
				}
				///<summary>
				/// Returns casted info.
				///</summary>
				property ParameterInfo_Int64 ^IntInfo
				{
					ParameterInfo_Int64 ^get()
					{ return _info; }
				}
		};
		///<summary>
		/// Wrapper, that provides double property for value.
		///</summary>
		public ref class ParameterDouble :public Parameter
		{
			private:
				ParameterInfo_Double ^_info;
			public:
				ParameterDouble(System::String ^name, ParameterInfo_Double ^info, ParameterSet ^owner)
					:Parameter(name, info, owner, "DoubleValue")
				{ _info = info; }
				///<summary>
				/// Int version for Value property.
				///</summary>
				property double DoubleValue
				{
					double get();
					void set(double value);
				}
				///<summary>
				/// Returns casted info.
				///</summary>
				property ParameterInfo_Double ^DoubleInfo
				{
					ParameterInfo_Double ^get()
					{ return _info; }
				}
		};
	}
}
